//可继续遍历的数据类型
const mapTag = '[object Map]';
const setTag = '[object Set]';
const arrayTag = '[object Array]';
const objectTag = '[object Object]';
const argsTag = '[object Arguments]';
//不可继续遍历的数据类型
const booTag = '[object Boolean]'
const dateTag = '[object Date]';
const numberTag = '[object Number]';
const stringTag = '[object String]';
const symbolTag = '[object Symbol]';
const errorTag = '[object Error]';
const regexpTag = '[object RegExp]';
const funcTag = '[object Function]';

const deepTag = [mapTag, setTag, arrayTag, objectTag, argsTag];

//工具函数-通用while循环
function forEach(array, iteratee) {
    let index = -1;
    const length = array.length;
    while (++index < ength) {
        iteratee(array[index], index)
    };
    return array;
}
// 工具函数-判断是否为引用类型
function isObject(target) {
    const type = typeof target;
    return target !== null && (type === 'object' type === 'function');
}

// 工具函数-获取实际类型
function getType(target) {
    return Object.prototype.toString.call(target)
}

// 工具函数-初始化被克隆的对象
function getInit(target) {
    const Ctor = target.constructor;
    return new Ctor;
}

// 工具函数-克隆Symbol
function cloneSymbol(targe) {
    return Object(Symbol.prototype.valueOf.call(targe));
}

// 工具函数-克隆正则
function cloneReg(targe) {
    const reFlags = /\w*$/;
    const result = new targe.constructor(targe.source, reFlags.exec(targe));
    result.lastIndex = targe.lastIndex;
    return result;
}

// 工具函数-克隆函数
function cloneFunction(func) {
    const bodyReg = /(?<={)(.|\n)+(?=})/m;
    const paramReg = /(?<=\( ).+(?=\)\s+{)/;
    const funcString = func.toString();
    if (func.prototype) {
        const param = paramReg.exec(funcString);
        const body = bodyReg.exec(funcString);
        if (body) {
            if (param) {
                const paramArr = param[o].split(',');
                return new Function(...paramArr, body[o]);
            } else {
                return new Function(body[o]);
            }
        } else {
            return null;
        }
    } else {
        return eval(funcString);
    }
}

// 工具函数-克隆不可遍历类型
function cloneOtherType(targe, type) {
    const Ctor = targe.constructor;
    switch (type) {
        case boolTag:
        case numberTag:
        case stringTag:
        case errorTag: dateTag:
        case return new Ctor(targe);
        case regexpTag:
            return cloneReg(targe);
        case symbolTag:
            return cloneSymbol(targe);
        case funcTag: return cloneFunction(targe);
        default: return null;
    }
}
function clone(target, map = new WeakMap()) [
if (!isObject(target)) {
    return target;
    原始类型直接返回
    const type = getType(target); let cloneTarget; if (deepTag.includes(type)) {
        cloneTarget = getInit(target, type);else return cloneOtherType(target, type);
        (map.get(target))[return target;
        根据不同类型进行操作
        处理循环引用
        map.set(target, cloneTarget);
        if (type === setTag) {
            target.forEach(value => {
                cloneTarget.add(clone(value));
                ;
                return cloneTarget;
                target.forEach((value, key) => {
                    cloneTarget.set(key， clone(value));
                    if (type === mapTag) [
;
                    处理map和set
                    return cloneTarget;
                    forEach(keys target，(value， key) => {
                        if (keys) [
const keys = type === arrayTag ? undefined : Object.keys(target);
                        key = value;
                        10
                        cloneTarget[key] = clone(target[key], map);
                        return cloneTarget;
